﻿//module;

/**
 * @author rayzhang
 * @desc 有序map, 使用QMap来存储数据，并用一个单独的数据结构（QVector）来存储键的插入顺序
 *
 */
#include <QVector>
#include <QMap>
//export module libflow.orderedmap;
/*export */namespace ray
{
template <typename K, typename V>
class OrderedMap
{
public:
    // 插入数据，如果key已经存在，则更新value
    void insert(const K& key, const V& value)
    {
        if (!data.contains(key)) {
            keysOrder.append(key);
        }
        data[key] = value;
    }

    V& operator[](const K& key)
    {
        if (!data.contains(key)) {
            keysOrder.append(key);
        }
        return data[key];
    }

    const V& operator[](const K& key) const { return const_cast<OrderedMap*>(this)->operator[](key); }

    QVector<K> keys() const { return keysOrder; }

    QVector<V> values() const
    {
        if (keysOrder.isEmpty()) {
            return {};
        }
        QVector<V> result;
        for (const auto& key : keysOrder) {
            result.append(data[key]);
        }
        return result;
    }

    bool contains(const K& key) const { return data.contains(key); }

    // 返回对应key的value，如果key不存在则返回默认构造的V类型对象
    V value(const K& key) const { return data.value(key); }

    // 返回索引处的值，如果索引无效，则返回默认构造的V类型对象
    V valueAt(int index) const
    {
        if (index >= 0 && index < keysOrder.size()) {
            return data.value(keysOrder[index]);
        }
        // throw std::out_of_range("Index out of range");
        return {};
    }

    // 返回索引处的键，如果索引无效，则返回默认构造的K类型对象
    K keyAt(int index) const
    {
        if (index >= 0 && index < keysOrder.size()) {
            return keysOrder[index];
        }
        // throw std::out_of_range("Index out of range");
        return {};
    }

    // 返回是否为空
    bool isEmpty() const { return data.isEmpty(); }

    // 大小
    int size() const { return std::min(keys().size(), values().size()); }

    // 清空
    void clear()
    {
        data.clear();
        keysOrder.clear();
    }

    // 移除
    void remove(const K& key)
    {
        keysOrder.removeOne(key);
        data.remove(key);
    }

private:
    QMap<K, V> data;
    QVector<K> keysOrder;
};
} // namespace ray
